package com.wurd.service;

import com.wurd.entity.Test;
import com.wurd.repository.TestRepository;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Random;
import java.util.UUID;

@Service
@Transactional
public class TestService {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private SessionFactory sessionFactory;

    @Autowired
    private HibernateTemplate hibernateTemplate;

    @Autowired
    private TestRepository testRepository;

    private int count = 0;

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void test1() {
        for (int i = 0; i < 2; i++) {
            testRepository.test();
//            Test test = new Test();
//            test.setName("1");
//            hibernateTemplate.save(test);

//            String sql = "from Test where 1=1";
//            if (i == 1) {
//                sql = sql + " or aa=1";
//            }
//            Query query = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(sql);
//            List rs = query.list();
//            System.out.print("");
        }
    }

    public void test() {
        count = count + 1;
        String sql = "select * from test where 1=1";
        String str = "性能方面：HikariCP因为细节方面优化力度较大，性能方面强于Druid" +
                "功能丰富程度方面：Druid功能更全面除了具有连接池的基本功能以外，还支持sql级监控，" +
                "支持扩展，防止SQL注入等功能。使用热度：Druid在国内使用较多，国内有很多生产实践。" +
                "HikariCP是spring boot 2.0以后默认连接池，在国外使用较多。";
        for (int i = 0; i < 20; i++) {
//            try {
//                Connection conn = dataSource.getConnection();
//                PreparedStatement stmt = conn.prepareStatement(sql);
//                ResultSet rs = stmt.executeQuery();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }

            new Thread(() -> {
                Random random = new Random();
                while (true) {
                    if (count > 2) {
                        break;
                    }
                    int r = random.nextInt(100000);
                    String c = " or id=" + r + " or name = '"
                            + String.format("% 100d", 1)
                            + System.nanoTime()
                            + UUID.randomUUID()
                            + String.format("% 1000d", 1) + str + "'";
                    String finalSql = sql + c;

//                    datasourceQuery(finalSql);

                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

//                    hibernateQuery(c, finalSql);

                    hibernateTemplateQuery(finalSql);

                }
            }).start();
        }
    }

    public void hibernateTemplateQuery(String finalSql) {
        org.hibernate.classic.Session session = null;
        try {
            session = hibernateTemplate.getSessionFactory().openSession();
            SQLQuery query2 = session.createSQLQuery(finalSql + " or name = ?");
            query2.setParameter(0, System.nanoTime() + UUID.randomUUID().toString());
            List rs = query2.list();
            System.out.print("");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) session.close();
        }
    }

    public void hibernateQuery(String c, String finalSql) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Query query = session.createQuery("from Test where name=? ");
            query.setParameter(0, "a");
            query.setParameter(1, c);
            List rs = query.list();
            SQLQuery query1 = session.createSQLQuery(finalSql + " or name = ?");
            query1.setParameter(0, "123");
            List rs1 = query.list();
            System.out.print("");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) session.close();
        }
    }

    public void datasourceQuery(String finalSql) {
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            PreparedStatement stmt = conn.prepareStatement(finalSql);
            ResultSet rs = stmt.executeQuery();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
